#include "base/base.hpp"
#include <string>
#include <boost/asio.hpp>
#include <boost/format.hpp>
#include <boost/shared_ptr.hpp>
#include <gflags/gflags.h>
#include <glog/logging.h>
#include "leveldb_service.pb.h"
#include "server/client_connection.hpp"

DEFINE_string(server,
              "localhost",
              "LevelDB server address");

DEFINE_string(port,
              "9999",
              "Port of the LevelDB server the client should connect to.");

DEFINE_int32(rpc_timeout_ms,
             10000,
             "RPC timeout in ms.");

DECLARE_bool(alsologtostderr);

using namespace boost;

int main(int argc, char* argv[]) {
  google::ParseCommandLineFlags(&argc, &argv, true);
  google::InitGoogleLogging(argv[0]);
  FLAGS_alsologtostderr = true;

  boost::shared_ptr<ClientConnection> channel(
      new ClientConnection("RPCMain", FLAGS_server, FLAGS_port));
  channel->Connect();
  levelserv::LevelDbService::Stub stub(channel.get());

  // Set k/v pairs.
  {
    levelserv::SetRequest request;
    request.set_key_namespace("test");
    for (int i = 0; i < 10; ++i) {
      levelserv::KeyValue* kv = request.add_kv();
      kv->set_key(str(format("key%s") % i));
      kv->set_value(str(format("value = %s") % i));
    }
    levelserv::SetResponse response;
    RpcController controller;
    stub.Set(&controller,
             &request,
             &response,
             NULL);
    controller.Wait(FLAGS_rpc_timeout_ms);
    if (controller.Failed()) {
      LOG(ERROR) << "Failed";
    } else {
      LOG(INFO) << response.DebugString();
    }
  }

  // Get k/v pairs.
  {
    levelserv::GetRequest request;
    request.set_key_namespace("test");
    for (int i = 0; i < 10; ++i) {
      request.add_key(str(format("key%s") % i));
    }
    levelserv::GetResponse response;
    RpcController controller;
    stub.Get(&controller,
             &request,
             &response,
             NULL);
    controller.Wait(FLAGS_rpc_timeout_ms);
    if (controller.Failed()) {
      LOG(ERROR) << "Failed";
    } else {
      LOG(INFO) << response.DebugString();
    }
  }

  return 0;
}
